package com.ly.demo.thread.syn;

/**
 * @author liuyang
 * @des
 * @Version 1.0
 * @Date: 22/10/2021 10:18
 */

/**
 * 5.使用局部变量实现线程同步
 * 如果使用ThreadLocal管理变量，则每一个使用该变量的线程都获得该变量的副本，
 * 副本之间相互独立，这样每一个线程都可以随意修改自己的变量副本，而不会对其他线程产生影响。
 * ThreadLocal 类的常用方法
 * ThreadLocal() : 创建一个线程本地变量
 * get() : 返回此线程局部变量的当前线程副本中的值
 * initialValue() : 返回此线程局部变量的当前线程的"初始值"
 * set(T value) : 将此线程局部变量的当前线程副本中的值设置为value
 * 注：ThreadLocal与同步机制
 * a.ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题。
 * b.前者采用以"空间换时间"的方法，后者采用以"时间换空间"的方式
 */

public class ThreadLocalSynchronization {

    public class Bank {
        private ThreadLocal<Integer> account = new ThreadLocal<Integer>() {
            @Override
            protected Integer initialValue() {
                return 10;
            }
        };

        public int getAccount() {
            return account.get();
        }

        public void saveAccount(int money) {
            account.set(account.get() + money);
        }

    }

    class ThreadLocalThread implements Runnable {

        private Bank bank;

        public ThreadLocalThread(Bank bank) {
            this.bank = bank;
        }

        @Override
        public void run() {

            for (int i = 0; i < 10; i++) {
                bank.saveAccount(10);

                System.out.println(Thread.currentThread().getName() + "-->当前余额：" + bank.getAccount() + "元。");
            }

        }
    }

    public void userReentrantLockThread() {
        Bank bank = new Bank();
        ThreadLocalThread threadLocalThread = new ThreadLocalThread(bank);

        Thread thread1 = new Thread(threadLocalThread);
        Thread thread2 = new Thread(threadLocalThread);

        thread1.start();
        thread2.start();

    }

    public static void main(String[] args) {
        ThreadLocalSynchronization threadLocalSynchronization = new ThreadLocalSynchronization();
        threadLocalSynchronization.userReentrantLockThread();
    }
}
